
import time
import os
import requests
import logging
from datetime import datetime
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

from minio import Minio
from minio.error import S3Error

# 创建 logs 目录（如果不存在）
log_dir = "logs"
if not os.path.exists(log_dir):
    os.makedirs(log_dir)

# 配置日志系统
log_filename = datetime.now().strftime("%Y-%m-%d") + ".log"
log_filepath = os.path.join(log_dir, log_filename)

# 创建日志记录器
logger = logging.getLogger("ImageUploader")
logger.setLevel(logging.INFO)

# 创建文件处理器
file_handler = logging.FileHandler(log_filepath,  encoding='utf-8')
file_handler.setLevel(logging.INFO)

# 创建控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)

# 创建格式化器
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)

# 添加处理器到记录器
logger.addHandler(file_handler)
logger.addHandler(console_handler)

# 初始化 MinIO 客户端
minio_client = Minio(
    "8.137.58.206:9000",        # 替换为你的MinIO服务器地址
    access_key="9eBv4Rt6",      # 替换为你的Access Key
    secret_key="3a7W5Mz8",      # 替换为你的Secret Key
    secure=False                # 如果使用HTTPS(SSL/TLS)则为True，本地测试通常为False
)

class ImageUploadHandler(FileSystemEventHandler):
    def __init__(self, watch_path):
        self.watch_path = watch_path
        self.retry_queue = []
        # 确保MinIO桶存在
        self.ensure_bucket_exists("bucket1")
        logger.info(f"初始化监控器，监控路径: {watch_path}")

    def ensure_bucket_exists(self, bucket_name):
        try:
            if not minio_client.bucket_exists(bucket_name):
                minio_client.make_bucket(bucket_name)
                logger.info(f"创建桶: {bucket_name}")
            else:
                logger.info(f"桶已存在: {bucket_name}")
        except S3Error as err:
            logger.error(f"检查桶失败: {err}")

    def wait_for_file_stable(self, file_path, check_interval=1, max_wait=10):
        """等待文件大小稳定"""
        size = -1
        wait_time = 0
        while wait_time < max_wait:
            try:
                current_size = os.path.getsize(file_path)
            except OSError:
                current_size = -1
            if current_size == size:
                return True
            size = current_size
            time.sleep(check_interval)
            wait_time += check_interval
        return False

    def on_created(self, event):
        # 不区分大小写的扩展名检查
        extensions = ['.jpg', '.png', '.jpeg', '.bmp']
        file_path = event.src_path
        if not event.is_directory and any(file_path.lower().endswith(ext) for ext in extensions):
            logger.info(f"检测到新文件: {file_path}")
            # 等待文件完全写入
            if self.wait_for_file_stable(file_path):
                self.upload_file(file_path)
            else:
                logger.warning(f"文件未稳定，放弃上传: {file_path}")

    def upload_file(self, file_path, max_retries=3):
        for attempt in range(max_retries):
            timestamp = str(int(time.time()))
            # 保留原始文件扩展名
            original_ext = os.path.splitext(file_path)[1].lower()
            object_name = timestamp + original_ext
            bucket_name = "bucket1"
            try:
                minio_client.fput_object(
                    bucket_name,
                    object_name,
                    file_path,
                )
                logger.info(f"图片 {file_path} 已成功上传为对象 {object_name}")
                os.remove(file_path)  # 删除本地文件
                return True
            except S3Error as err:
                logger.error(f"MinIO上传失败（尝试 {attempt + 1}/{max_retries}）: {err}")
            except Exception as e:
                logger.error(f"上传异常（尝试 {attempt + 1}/{max_retries}）: {e}")
            time.sleep(2 ** attempt)  # 指数退避
        logger.error(f"放弃上传，保留文件: {file_path}")
        return False

    def start_monitoring(self):
        """开始监控"""
        observer = Observer()
        observer.schedule(self, self.watch_path, recursive=False)
        observer.start()
        logger.info(f"开始监控目录: {self.watch_path}")
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            observer.stop()
            logger.info("监控已停止")
        observer.join()

# 使用示例
if __name__ == "__main__":
    # 替换为您的实际监控目录
    # watch_path = "/home/nvidia/Downloads/PYPRO/test_folder/"
    watch_path = "C:/Users/96523/Downloads/test"
    handler = ImageUploadHandler(watch_path=watch_path)
    handler.start_monitoring()
